


#include <stdio.h>
#include <unistd.h>
#include <hi_time.h>

#include "ohos_init.h"
#include "cmsis_os2.h"
#include "iot_gpio.h"
#include "led_example.h"
#include "iot_gpio_ex.h"

#define LED_INTERVAL_TIME_US 300000
#define LED_TASK_STACK_SIZE 4096
#define LED_TASK_PRIO 28

//#define DHT11_GPIO  IOT_IO_NAME_GPIO_1											   
#define	DHT11_DQ_OUT_High  IoTGpioSetOutputVal(IOT_IO_NAME_GPIO_5, 1); //设置GPIO输出高电平
#define	DHT11_DQ_OUT_Low  IoTGpioSetOutputVal(IOT_IO_NAME_GPIO_5, 0); //设置GPIO输出低电平  
/****************************************
设置端口为输出
*****************************************/
double ss;
IotGpioValue input = 0;
 
int hu,tm;
void DHT11_IO_OUT(void)
{
    //设置GPIO_11为输出模式
    IoTGpioSetDir(IOT_IO_NAME_GPIO_5, IOT_GPIO_DIR_OUT);
}
//初始化DHT11的IO口 DQ 同时检测DHT11的存在
//返回1:不存在
//返回0:存在    	 
 

unsigned char GPIOGETINPUT(IotIoName id,IotGpioValue *val)
{
    IoTGpioGetInputVal(id,val);
    return *val;
}
 unsigned char DHT11_Check(void) 	   
{   
	unsigned char  retry=0;
	  DHT11_IO_IN();//SET INPUT	 
    while (GPIOGETINPUT(IOT_IO_NAME_GPIO_5,&input)&&retry<100)//DHT11会拉低40~80us
	{
		retry++;
		hi_udelay(1);
	};	 
	if(retry>=100)return 1;
	else retry=0;
    
    while ((!GPIOGETINPUT(IOT_IO_NAME_GPIO_5,&input))&&retry<100)//DHT11拉低后会再次拉高40~80us
	{
		retry++;
		hi_udelay(1);
	};
	if(retry>=100)return 1;	   
	return 0;
}





 unsigned char DHT11_Init(void)
{	 
	
    //设置GPIO_11的复用功能为普通GPIO
	IoSetFunc(IOT_IO_NAME_GPIO_5, IOT_IO_FUNC_GPIO_5_GPIO); 
    //设置GPIO_11为输出模式
    IoTGpioSetDir(IOT_IO_NAME_GPIO_5, IOT_GPIO_DIR_OUT);
		 //设置GPIO_11输出高电平
    IoTGpioSetOutputVal(IOT_IO_NAME_GPIO_5, 1);		    
	DHT11_Rst();  //复位DHT11
	return DHT11_Check();//等待DHT11的回应
} 

//复位DHT11
void DHT11_Rst(void)	   
{                
	DHT11_IO_OUT(); 	//SET OUTPUT
   DHT11_DQ_OUT_Low; 	//拉低DQ
    hi_udelay(20000);//拉低至少18ms  20000
   DHT11_DQ_OUT_High; 	//DQ=1 
	hi_udelay(30);     	//主机拉高20~40us
}



//获取GPIO输入状态
 
/****************************************
设置端口为输入
*****************************************/
void DHT11_IO_IN(void)
{
    IoTGpioSetDir(IOT_IO_NAME_GPIO_5, IOT_GPIO_DIR_IN);//配置为输入模式
    IoSetPull(IOT_IO_NAME_GPIO_5, IOT_IO_PULL_NONE);//配置为浮空输入
} 

//等待DHT11的回应
//返回1:未检测到DHT11的存在
//返回0:存在
 


//从DHT11读取一个位
//返回值：1/0
unsigned char DHT11_Read_Bit(void) 			 
{
 	unsigned char  retry=0;
  while(GPIOGETINPUT(IOT_IO_NAME_GPIO_5,&input)&&retry<100){//等待变为低电平
        retry++;
        hi_udelay(1);
    }
    retry=0;
    while((!GPIOGETINPUT(IOT_IO_NAME_GPIO_5,&input))&&retry<100){//等待变高电平
        retry++;
        hi_udelay(1);
    }
    hi_udelay(40);//等待40us	//用于判断高低电平，即数据1或0
    if(GPIOGETINPUT(IOT_IO_NAME_GPIO_5,&input))return 1; else return 0;
}
//从DHT11读取一个字节
//返回值：读到的数据
 unsigned char DHT11_Read_Byte(void)    
{        
    unsigned char i,dat;
    dat=0;
	for (i=0;i<8;i++) 
	{
   		dat<<=1; 
	    dat|=DHT11_Read_Bit();
    }
  					    
    return dat;
}
//从DHT11读取一次数据
//temp:温度值(范围:0~50°)
//humi:湿度值(范围:20%~90%)
//返回值：0,正常;1,读取失败
 unsigned char DHT11_Read_Data(unsigned char *temp,unsigned char *humi)    
{        
 	unsigned char  buf[5]={0};
	unsigned char  i;
	DHT11_Rst();
	if(DHT11_Check()==0)
	{   
        printf("start111111 \n");
		for(i=0;i<5;i++)//读取40位数据
		{
			buf[i]=DHT11_Read_Byte();
		}
		/*if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])//数据校验
		{
			*humi=buf[0];
			*temp=buf[2];
            printf("%d--%d---%d-----%d",(unsigned int)buf[0],(unsigned int)buf[2]);
		}*/
    
	}else return 1;
    
	hu=(unsigned int)buf[0];
    tm=(unsigned int)buf[2];
    hi_sleep(1000);
    return 0;
 	    
}
void *SCALE3(const char *arg)
 {  
     unsigned char *temp,*humi;
    (void)arg;
    printf("11111111 \n");
    while(1){
         DHT11_Read_Byte();
         DHT11_Read_Data(temp,humi);

         printf("%d \n",hu);
         printf("%d \n",tm);
         DHT11_Init();

       
        hi_sleep(500);
  

    }
   

 }

static void DHT11ExampleEntry(void)
{
    osThreadAttr_t attr;
    

    attr.name = "SCALE3";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = LED_TASK_STACK_SIZE;
    attr.priority = LED_TASK_PRIO;

    if (osThreadNew((osThreadFunc_t)SCALE3, NULL, &attr) == NULL) {
        printf("[DHT11] Falied to create SCALE!\n");
    }
    return NULL;
}



SYS_RUN(DHT11ExampleEntry);






